package com.hsy.order.base.ui.widget

import android.app.Activity
import android.content.Context
import android.text.TextUtils
import android.view.View
import android.webkit.JsPromptResult
import android.webkit.WebChromeClient
import android.webkit.WebView

import com.flux.utils.LogUtil
import com.flux.utils.ToastUtil
import com.hsy.order.utils.CommonUtils

import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject

/**
 * Created by MartinKent on 2016/8/16.
 */
abstract class BaseWebViewHandler(private val activity: Activity) : BaseWebView.Client() {

    override fun onJsPrompt(client: WebChromeClient, view: WebView, url: String, message: String, defaultValue: String, result: JsPromptResult): Boolean {
        return handle(view, url, message, defaultValue, result)
    }

    override fun onReceivedTitle(client: WebChromeClient, view: WebView, title: String) {
        onSetTitle(title)
    }

    override fun onProgressChanged(client: WebChromeClient, view: WebView, newProgress: Int) {
        super.onProgressChanged(client, view, newProgress)
        if (0 == newProgress && !CommonUtils.isProgressDialogShowing) {
            CommonUtils.showProgressDialog(activity)
        } else if (newProgress >= 100) {
            CommonUtils.hideProgressDialog()
        }
    }

    fun showToast(msgRes: Int) {
        ToastUtil.showToast(activity, activity.getString(msgRes))
    }

    fun showToast(msg: String) {
        ToastUtil.showToast(activity, msg)
    }

    fun setViewVisibility(v: Int, vararg views: View) {
        if (v == View.VISIBLE || v == View.INVISIBLE || v == View.GONE) {
            for (view in views) {
                when (v) {
                    View.VISIBLE -> view.visibility = View.VISIBLE
                    View.INVISIBLE -> view.visibility = View.INVISIBLE
                    else -> view.visibility = View.GONE
                }
            }
        } else {
            LogUtil.e("visibility invalid")
        }
    }

    private fun handle(view: WebView, url: String, message: String, defaultValue: String, result: JsPromptResult): Boolean {
        LogUtil.i("handle url=$url,message=$message")
        try {
            val `object` = JSONObject(message)
            if (`object`.has("action")) {
                val actType = `object`.getString("action")
                LogUtil.i("action=" + actType)
                if (!TextUtils.isEmpty(actType)) {
                    if ("prompt".equals(actType, ignoreCase = true)) {
                        result.confirm()

                        return true
                    }
                    if ("back".equals(actType, ignoreCase = true)) {
                        onCloseWindow()
                    } else if ("open".equals(actType, ignoreCase = true)) {
                        var u = ""
                        if (`object`.has("url")) {
                            u = `object`.getString("url")
                        } else {
                            LogUtil.e("Expect field [url]")
                        }
                        var type = ""
                        if (`object`.has("type")) {
                            type = `object`.getString("type")
                        }
                        var title = ""
                        if (`object`.has("title")) {
                            title = `object`.getString("title")
                        }
                        var v = View.VISIBLE
                        if (`object`.has("backButtonVisibility")) {
                            v = Integer.valueOf(`object`.getString("backButtonVisibility"))!!
                        }
                        onOpenWindow(u, type, title, v)
                    } else if ("openForResult".equals(actType, ignoreCase = true)) {
                        var u = ""
                        if (`object`.has("url")) {
                            u = `object`.getString("url")
                        } else {
                            LogUtil.e("Expect field [url]")
                        }
                        var type = ""
                        if (`object`.has("type")) {
                            type = `object`.getString("type")
                        }
                        var title = ""
                        if (`object`.has("title")) {
                            title = `object`.getString("title")
                        }
                        var v = View.VISIBLE
                        if (`object`.has("backButtonVisibility")) {
                            v = Integer.valueOf(`object`.getString("backButtonVisibility"))!!
                        }
                        var reqCode = 0
                        if (`object`.has("reqCode")) {
                            reqCode = Integer.valueOf(`object`.getString("reqCode"))!!
                        }
                        var callback = ""
                        if (`object`.has("callback")) {
                            callback = `object`.getString("callback")
                        }
                        onOpenWindowForResult(callback, reqCode, u, type, title, v)
                    } else if ("finish".equals(actType, ignoreCase = true)) {
                        var data = ""
                        if (`object`.has("data")) {
                            data = `object`.getString("data")
                        }
                        onFinish(data)
                    } else if ("toast".equals(actType, ignoreCase = true)) {
                        if (`object`.has("msg")) {
                            showToast(`object`.getString("msg"))
                        } else {
                            LogUtil.e("Expect field [msg]")
                        }
                    } else if ("setTitle".equals(actType, ignoreCase = true)) {
                        if (`object`.has("title")) {
                            onSetTitle(`object`.getString("title"))
                        } else {
                            LogUtil.e("Expect field [title]")
                        }
                    } else if ("setBackButtonVisibility".equals(actType, ignoreCase = true)) {
                        if (`object`.has("visibility")) {
                            onSetBackButtonVisibility(Integer.valueOf(`object`.getString("visibility"))!!)
                        } else {
                            LogUtil.e("Expect field [visibility]")
                        }
                    } else if ("setFunctionButtonText".equals(actType, ignoreCase = true)) {
                        if (`object`.has("text")) {
                            onSetFunctionButtonText(`object`.getString("text"))
                        }
                    } else if ("setFunctionButtonTextVisibility".equals(actType, ignoreCase = true)) {
                        if (`object`.has("visibility")) {
                            onSetFunctionButtonTextVisibility(Integer.valueOf(`object`.getString("visibility"))!!)
                        } else {
                            LogUtil.e("Expect field [visibility]")
                        }
                    } else if ("setFunctionButtonImage".equals(actType, ignoreCase = true)) {
                        if (`object`.has("img")) {
                            onSetFunctionButtonImage(activity, `object`.getString("img"))
                        }
                    } else if ("setFunctionButtonImageVisibility".equals(actType, ignoreCase = true)) {
                        if (`object`.has("visibility")) {
                            onSetFunctionButtonImageVisibility(Integer.valueOf(`object`.getString("visibility"))!!)
                        } else {
                            LogUtil.e("Expect field [visibility]")
                        }
                    } else if ("setFunctionButtonCallback".equals(actType, ignoreCase = true)) {
                        if (`object`.has("callback")) {
                            val callback = `object`.getString("callback")
                            var args: String? = null
                            if (`object`.has("args")) {
                                args = `object`.getString("args")
                            }
                            onSetFunctionButtonCallback(callback, args)
                        }
                    } else if ("setFunctionButtonVisibility".equals(actType, ignoreCase = true)) {
                        if (`object`.has("visibility")) {
                            onSetFunctionButtonVisibility(Integer.valueOf(`object`.getString("visibility"))!!)
                        } else {
                            LogUtil.e("Expect field [visibility]")
                        }
                    } else if ("setFunctionButtonClickable".equals(actType, ignoreCase = true)) {
                        if (`object`.has("clickable")) {
                            onSetFunctionButtonClickable(`object`.getBoolean("clickable"))
                        } else {
                            LogUtil.e("Expect field [clickable]")
                        }
                    } else if ("showDropDownMenu".equals(actType, ignoreCase = true)) {
                        if (`object`.has("data")) {
                            var callback: String? = null
                            if (`object`.has("callback")) {
                                callback = `object`.getString("callback")
                            }
                            onShowDropDownMenu(`object`.getJSONArray("data"), callback)
                        } else {
                            LogUtil.e("Expect field [visibility]")
                        }
                    } else if ("registerBackCallback".equals(actType, ignoreCase = true)) {
                        if (`object`.has("callback")) {
                            var preventDefault = false
                            if (`object`.has("preventDefault")) {
                                preventDefault = `object`.getBoolean("preventDefault")
                            }
                            onRegisterBackCallback(`object`.getString("callback"), preventDefault)
                        }
                    } else if ("registerResumeCallback".equals(actType, ignoreCase = true)) {
                        onRegisterResumeCallback()
                    } else if ("registerStopCallback".equals(actType, ignoreCase = true)) {
                        onRegisterStopCallback()
                    } else if ("cancelToast".equals(actType, ignoreCase = true)) {
                        ToastUtil.cancelToast()
                    }
                } else {
                    LogUtil.e("actType err")
                }
            } else {
                LogUtil.e("Expect field [action]")
            }
            result.confirm("")
        } catch (e: JSONException) {
            LogUtil.e("Not json")
            e.printStackTrace()
        }

        result.confirm()
        return true
    }

    private fun onRegisterStopCallback() {

    }

    private fun onRegisterResumeCallback() {

    }

    protected abstract fun onFinish(data: String)

    protected abstract fun onOpenWindowForResult(callback: String, reqCode: Int, u: String, type: String, title: String, v: Int)

    protected abstract fun onRegisterBackCallback(callback: String, preventDefault: Boolean)

    protected abstract fun onOpenWindow(u: String, type: String, title: String, v: Int)

    protected abstract fun onCloseWindow()

    protected abstract fun onSetFunctionButtonCallback(callback: String, args: String?)

    protected abstract fun onSetFunctionButtonImageVisibility(visibility: Int)

    protected abstract fun onSetFunctionButtonImage(context: Context, img: String)

    protected abstract fun onSetFunctionButtonTextVisibility(visibility: Int)

    protected abstract fun onSetFunctionButtonText(text: String)

    protected abstract fun onSetFunctionButtonVisibility(visibility: Int)

    protected abstract fun onSetFunctionButtonClickable(clickable: Boolean)

    protected abstract fun onSetBackButtonVisibility(visibility: Int)

    protected abstract fun onSetTitle(title: String)

    protected abstract fun onShowDropDownMenu(items: JSONArray, callback: String?)
}